<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
	<head>
		<title>Assemblies</title>
<link href="../docs-assets/Breadcrumbs.css" rel="stylesheet" rev="stylesheet" type="text/css">
		<meta name="viewport" content="width=device-width initial-scale=1">
		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
		<meta http-equiv="Content-Language" content="en-gb">

<link href="../docs-assets/Contents.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Progress.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Navigation.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Fonts.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Base.css" rel="stylesheet" rev="stylesheet" type="text/css">
<script>
MathJax = {
	tex: {
		inlineMath: '$', '$'], ['\\(', '\\)'
	},
	svg: {
		fontCache: 'global'
	}
};
</script>
<script type="text/javascript" id="MathJax-script" async
	src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-svg.js">
</script>

<script>
function togglePopup(material_id) {
  var popup = document.getElementById(material_id);
  popup.classList.toggle("show");
}
</script>

<link href="../docs-assets/Popups.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Colours.css" rel="stylesheet" rev="stylesheet" type="text/css">
		
	</head>
	<body class="commentary-font">
		<nav role="navigation">
		<h1><a href="../index.html"><img src="../docs-assets/Inform.png" height=72> </a></h1>
<ul><li><a href="../index.html">home</a></li>
</ul><h2>Compiler</h2><ul>
<li><a href="../structure.html">structure</a></li>
<li><a href="../inbuildn.html">inbuild</a></li>
<li><a href="../inform7n.html">inform7</a></li>
<li><a href="../intern.html">inter</a></li>
<li><a href="../services.html">services</a></li>
<li><a href="../secrets.html">secrets</a></li>
</ul><h2>Other Tools</h2><ul>
<li><a href="../inblorbn.html">inblorb</a></li>
<li><a href="../inform6.html">inform6</a></li>
<li><a href="../inpolicyn.html">inpolicy</a></li>
</ul><h2>Resources</h2><ul>
<li><a href="../extensions.html">extensions</a></li>
<li><a href="../kits.html">kits</a></li>
</ul><h2>Repository</h2><ul>
<li><a href="https://github.com/ganelson/inform"><img src="../docs-assets/github.png" height=0> github</a></li>
</ul><h2>Related Projects</h2><ul>
<li><a href="https://github.com/ganelson/inweb"><img src="../docs-assets/github.png" height=0> inweb</a></li>
<li><a href="https://github.com/ganelson/intest"><img src="../docs-assets/github.png" height=0> intest</a></li>
</ul>
		</nav>
		<main role="main">
		<!-- Weave of 'Assemblies' generated by inweb -->
<div class="breadcrumbs">
    <ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="../inform7n.html">Inform7</a></li><li><a href="index.html">assertions</a></li><li><a href="index.html#4">Chapter 4: Assertions</a></li><li><b>Assemblies</b></li></ul></div>
<p class="purpose">To build the complex multi-object assemblies which result from allowing the source text to say things like "in every room is a vehicle".</p>

<ul class="toc"><li><a href="4-ass2.html#SP5">&#167;5. Initialisation</a></li><li><a href="4-ass2.html#SP8">&#167;8. New generalisations</a></li><li><a href="4-ass2.html#SP10">&#167;10. The assembly process</a></li></ul><hr class="tocbar">

<p class="commentary firstcommentary"><a id="SP1" class="paragraph-anchor"></a><b>&#167;1. </b>Assemblies are made when an object of a given kind is created, and when
generalisations about that kind mean that further creations are also
needed. For instance: if a generalisation has said that every container
contains a shoe, then each time a container is created, we also need to
create a shoe, and assert a spatial relationship between them.
</p>

<p class="commentary">In practice we do this by a simple process which involves cutting and
pasting of subtrees of the parse tree, which motivates the following
data structure.
</p>

<p class="commentary firstcommentary"><a id="SP2" class="paragraph-anchor"></a><b>&#167;2. </b>Generalisations are essentially fragments of parse tree stored for later use.
They handle sentences like
</p>

<blockquote>
    <p>In every container is a coin.</p>
</blockquote>

<p class="commentary">which are done by recognising the prototype part ("in every container") in
the parse tree and grafting on a duplicate of the assembly part ("a coin")
in place of the <span class="extract"><span class="extract-syntax">EVERY_NT</span></span> subtree ("every container"). Sometimes the EVERY
subtree is the whole prototype subtree ("Every coin is on a table"), in
which case <span class="extract"><span class="extract-syntax">px</span></span> and <span class="extract"><span class="extract-syntax">substitute_at</span></span> in the following structure coincide.
</p>

<p class="commentary">Each kind (in this example "container") keeps a linked list of the
generalisations which apply to it.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">generalisation</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">look_for</span><span class="plain-syntax">; </span><span class="comment-syntax"> prototype situation to look for</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">what_to_make</span><span class="plain-syntax">; </span><span class="comment-syntax"> subtree for what to assemble</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">substitute_at</span><span class="plain-syntax">; </span><span class="comment-syntax"> position under </span><span class="extract"><span class="extract-syntax">look_for</span></span><span class="comment-syntax"> of the EVERY node</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">generalisation</span><span class="plain-syntax"> *</span><span class="identifier-syntax">next</span><span class="plain-syntax">; </span><span class="comment-syntax"> next in list of generalisations about kind</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">CLASS_DEFINITION</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">generalisation</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>The structure generalisation is accessed in 2/ptmn, 2/cs, 2/ps, 2/is, 3/dlr, 3/pr, 3/tr, 3/nuor, 3/uor, 3/tr2, 3/dbtr, 3/rpr, 3/nar, 3/nlpr, 3/nrr, 3/npr, 3/nvr, 3/nar2, 3/ldr, 4/rpt, 4/tc, 4/ass, 4/npa, 4/rk, 4/imp, 5/id, 5/adf, 5/rcd, 6/rlb, 6/act, 7/tbl, 7/eqt, 8/tcp, 8/abp, 8/cu and here.</li></ul>
<p class="commentary firstcommentary"><a id="SP3" class="paragraph-anchor"></a><b>&#167;3. </b>For reasons to do with timing, each object needs to keep track of which
generalisations have and have not yet applied to it. In practice, this is
a list of pairs \((K, g)\) where \(K\) is a kind and \(g\) is the most recent one
applied from \(K\)'s list.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">application</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">generalisation_owner</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">generalisation</span><span class="plain-syntax"> *</span><span class="identifier-syntax">latest_applied</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">application</span><span class="plain-syntax"> *</span><span class="identifier-syntax">next</span><span class="plain-syntax">;</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">application</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>The structure application is accessed in 2/ptmn, 2/cs, 2/ps, 2/is, 3/dlr, 3/pr, 3/tr, 3/nuor, 3/uor, 3/tr2, 3/dbtr, 3/rpr, 3/nar, 3/nlpr, 3/nrr, 3/npr, 3/nvr, 3/nar2, 3/ldr, 4/rpt, 4/tc, 4/ass, 4/npa, 4/rk, 4/imp, 5/id, 5/adf, 5/rcd, 6/rlb, 6/act, 7/tbl, 7/eqt, 8/tcp, 8/abp, 8/cu and here.</li></ul>
<p class="commentary firstcommentary"><a id="SP4" class="paragraph-anchor"></a><b>&#167;4. </b>These structures are combined in the following packet of data attached to
each inference subject:
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">assemblies_data</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">generalisation</span><span class="plain-syntax"> *</span><span class="identifier-syntax">generalisation_list</span><span class="plain-syntax">; </span><span class="comment-syntax"> kinds only: assembly instructions, if any</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">application</span><span class="plain-syntax"> *</span><span class="identifier-syntax">applications_so_far</span><span class="plain-syntax">; </span><span class="comment-syntax"> instances only: progress</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">named_after</span><span class="plain-syntax">; </span><span class="comment-syntax"> name derived from another: e.g. "Jane's nose"</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">named_after_text</span><span class="plain-syntax">; </span><span class="comment-syntax"> text of the derived part, e.g. "nose"</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">assemblies_data</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>The structure assemblies_data is private to this section.</li></ul>
<p class="commentary firstcommentary"><a id="SP5" class="paragraph-anchor"></a><b>&#167;5. Initialisation.</b></p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Assertions::Assemblies::initialise_assemblies_data</span><span class="plain-syntax">(</span><span class="reserved-syntax">assemblies_data</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ad</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">ad</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">generalisation_list</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">ad</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">applications_so_far</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">ad</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">named_after</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">ad</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">named_after_text</span><span class="plain-syntax"> = </span><span class="identifier-syntax">EMPTY_WORDING</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP6" class="paragraph-anchor"></a><b>&#167;6. </b>Setting the naming-after information.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Assertions::Assemblies::name_object_after</span><button class="popup" onclick="togglePopup('usagePopup1')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup1">Usage of <span class="code-font"><span class="function-syntax">Assertions::Assemblies::name_object_after</span></span>:<br/>The Creator - <a href="4-tc.html#SP8_4_1">&#167;8.4.1</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">infs</span><span class="plain-syntax">, </span><span class="identifier-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">after</span><span class="plain-syntax">, </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">assemblies_data</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ad</span><span class="plain-syntax"> = </span><span class="identifier-syntax">InferenceSubjects::get_assemblies_data</span><span class="plain-syntax">(</span><span class="identifier-syntax">infs</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">ad</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">named_after</span><span class="plain-syntax"> = </span><span class="identifier-syntax">after</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">ad</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">named_after_text</span><span class="plain-syntax"> = </span><span class="identifier-syntax">W</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP7" class="paragraph-anchor"></a><b>&#167;7. </b>And reading it again.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="identifier-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="function-syntax">Assertions::Assemblies::what_this_is_named_after</span><span class="plain-syntax">(</span><span class="identifier-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">infs</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">assemblies_data</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ad</span><span class="plain-syntax"> = </span><span class="identifier-syntax">InferenceSubjects::get_assemblies_data</span><span class="plain-syntax">(</span><span class="identifier-syntax">infs</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">ad</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">named_after</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>

<span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="function-syntax">Assertions::Assemblies::get_named_after_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">infs</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">assemblies_data</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ad</span><span class="plain-syntax"> = </span><span class="identifier-syntax">InferenceSubjects::get_assemblies_data</span><span class="plain-syntax">(</span><span class="identifier-syntax">infs</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">ad</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">named_after_text</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP8" class="paragraph-anchor"></a><b>&#167;8. New generalisations.</b>Here a new generalisation is made. The <span class="extract"><span class="extract-syntax">look_for</span></span> subtree contains the
<span class="extract"><span class="extract-syntax">EVERY_NT</span></span> node, but it might be either at the top, as here:
</p>

<blockquote>
    <p>Every container is in the Lumber Room.</p>
</blockquote>

<p class="commentary">or the first child of a <span class="extract"><span class="extract-syntax">RELATIONSHIP_NT</span></span> node, as here:
</p>

<blockquote>
    <p>In every container is a vehicle.</p>
</blockquote>

<p class="commentary">In the second case the <span class="extract"><span class="extract-syntax">what_to_make</span></span> subtree is an <span class="extract"><span class="extract-syntax">COMMON_NOUN_NT</span></span>, and in the
first it's a <span class="extract"><span class="extract-syntax">RELATIONSHIP_NT</span></span> subtree.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Assertions::Assemblies::make_generalisation</span><button class="popup" onclick="togglePopup('usagePopup2')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup2">Usage of <span class="code-font"><span class="function-syntax">Assertions::Assemblies::make_generalisation</span></span>:<br/>Assertions - <a href="4-ass.html#SP6_3_31">&#167;6.3.31</a>, <a href="4-ass.html#SP6_3_34_2">&#167;6.3.34.2</a>, <a href="4-ass.html#SP6_3_35">&#167;6.3.35</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">look_for</span><span class="plain-syntax">, </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">what_to_make</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">EVERY_node</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Node::get_type</span><span class="plain-syntax">(</span><span class="identifier-syntax">look_for</span><span class="plain-syntax">) == </span><span class="identifier-syntax">EVERY_NT</span><span class="plain-syntax">) </span><span class="identifier-syntax">EVERY_node</span><span class="plain-syntax"> = </span><span class="identifier-syntax">look_for</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">look_for</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">Node::get_type</span><span class="plain-syntax">(</span><span class="identifier-syntax">look_for</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax">) == </span><span class="identifier-syntax">EVERY_NT</span><span class="plain-syntax">))</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">EVERY_node</span><span class="plain-syntax"> = </span><span class="identifier-syntax">look_for</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"Generalisation without EVERY node"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">k</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Node::get_subject</span><span class="plain-syntax">(</span><span class="identifier-syntax">EVERY_node</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">k</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"Malformed EVERY node"</span><span class="plain-syntax">);</span>

<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><a href="4-ass2.html#SP9" class="function-link"><span class="function-syntax">Assertions::Assemblies::subtree_mentions_kind</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">look_for</span><span class="plain-syntax">,</span><span class="identifier-syntax">k</span><span class="plain-syntax">,0)) ||</span>
<span class="plain-syntax">        (</span><a href="4-ass2.html#SP9" class="function-link"><span class="function-syntax">Assertions::Assemblies::subtree_mentions_kind</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">what_to_make</span><span class="plain-syntax">,</span><span class="identifier-syntax">k</span><span class="plain-syntax">,0)))</span>
<span class="plain-syntax">        </span><span class="named-paragraph-container code-font"><a href="4-ass2.html#SP8_5" class="named-paragraph-link"><span class="named-paragraph">Issue an infinite regress of assemblies problem message</span><span class="named-paragraph-number">8.5</span></a></span><span class="plain-syntax">;</span>

<span class="plain-syntax">    </span><span class="named-paragraph-container code-font"><a href="4-ass2.html#SP8_1" class="named-paragraph-link"><span class="named-paragraph">Forbid generalisation about fixed kinds</span><span class="named-paragraph-number">8.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="named-paragraph-container code-font"><a href="4-ass2.html#SP8_2" class="named-paragraph-link"><span class="named-paragraph">Forbid generalisation on both sides</span><span class="named-paragraph-number">8.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="named-paragraph-container code-font"><a href="4-ass2.html#SP8_3" class="named-paragraph-link"><span class="named-paragraph">If we have to make a kind qualified by adjectives, expand that into a suitable subtree</span><span class="named-paragraph-number">8.3</span></a></span><span class="plain-syntax">;</span>

<span class="plain-syntax">    </span><span class="identifier-syntax">Node::set_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">EVERY_node</span><span class="plain-syntax">, </span><span class="identifier-syntax">EMPTY_WORDING</span><span class="plain-syntax">);</span>

<span class="plain-syntax">    </span><span class="reserved-syntax">generalisation</span><span class="plain-syntax"> *</span><span class="identifier-syntax">g</span><span class="plain-syntax"> = </span><span class="identifier-syntax">CREATE</span><span class="plain-syntax">(</span><span class="reserved-syntax">generalisation</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">g</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">look_for</span><span class="plain-syntax"> = </span><span class="identifier-syntax">look_for</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">g</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">what_to_make</span><span class="plain-syntax"> = </span><span class="identifier-syntax">what_to_make</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">g</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">substitute_at</span><span class="plain-syntax"> = </span><span class="identifier-syntax">EVERY_node</span><span class="plain-syntax">;</span>

<span class="plain-syntax">    </span><span class="named-paragraph-container code-font"><a href="4-ass2.html#SP8_4" class="named-paragraph-link"><span class="named-paragraph">Add this new generalisation to the list for the kind it applies to</span><span class="named-paragraph-number">8.4</span></a></span><span class="plain-syntax">;</span>

<span class="plain-syntax">    </span><span class="identifier-syntax">Annotations::write_int</span><span class="plain-syntax">(</span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax">, </span><span class="identifier-syntax">you_can_ignore_ANNOT</span><span class="plain-syntax">, </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">);</span>

<span class="plain-syntax">    </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">ASSEMBLIES</span><span class="plain-syntax">, </span><span class="string-syntax">"Assembly on $j:\n- - - -\nLook for: $T\nMake: $T- - - -\n\n"</span><span class="plain-syntax">,</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">k</span><span class="plain-syntax">, </span><span class="identifier-syntax">g</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">look_for</span><span class="plain-syntax">, </span><span class="identifier-syntax">g</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">what_to_make</span><span class="plain-syntax">);</span>

<span class="plain-syntax">    </span><a href="4-ass2.html#SP10" class="function-link"><span class="function-syntax">Assertions::Assemblies::ensure_all_generalisations_made</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">k</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP8_1" class="paragraph-anchor"></a><b>&#167;8.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Forbid generalisation about fixed kinds</span><span class="named-paragraph-number">8.1</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">instance_kind</span><span class="plain-syntax"> = </span><span class="identifier-syntax">KindSubjects::to_nonobject_kind</span><span class="plain-syntax">(</span><span class="identifier-syntax">k</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">instance_kind</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax">        (</span><span class="identifier-syntax">Kinds::Behaviour::is_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">instance_kind</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax">        (</span><span class="identifier-syntax">Kinds::Behaviour::has_named_constant_values</span><span class="plain-syntax">(</span><span class="identifier-syntax">instance_kind</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"$T"</span><span class="plain-syntax">, </span><span class="identifier-syntax">look_for</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"$T"</span><span class="plain-syntax">, </span><span class="identifier-syntax">what_to_make</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_AssemblyOnFixedKind</span><span class="plain-syntax">),</span>
<span class="plain-syntax">            </span><span class="string-syntax">"this generalisation can't be made"</span><span class="plain-syntax">,</span>
<span class="plain-syntax">            </span><span class="string-syntax">"because I only use generalisations to talk about values which can be "</span>
<span class="plain-syntax">            </span><span class="string-syntax">"created as needed, like things or scenes - not about those always "</span>
<span class="plain-syntax">            </span><span class="string-syntax">"existing in fixed ranges, like numbers or times."</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-ass2.html#SP8">&#167;8</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP8_2" class="paragraph-anchor"></a><b>&#167;8.2. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Forbid generalisation on both sides</span><span class="named-paragraph-number">8.2</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">what_to_make</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">Node::get_type</span><span class="plain-syntax">(</span><span class="identifier-syntax">what_to_make</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax">) == </span><span class="identifier-syntax">EVERY_NT</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"$T"</span><span class="plain-syntax">, </span><span class="identifier-syntax">look_for</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"$T"</span><span class="plain-syntax">, </span><span class="identifier-syntax">what_to_make</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_AssemblyOnBothSides</span><span class="plain-syntax">),</span>
<span class="plain-syntax">            </span><span class="string-syntax">"this generalisation can't be made"</span><span class="plain-syntax">,</span>
<span class="plain-syntax">            </span><span class="string-syntax">"because it uses 'every' or some similar generalisation on both sides, "</span>
<span class="plain-syntax">            </span><span class="string-syntax">"which is too rich for my taste."</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-ass2.html#SP8">&#167;8</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP8_3" class="paragraph-anchor"></a><b>&#167;8.3. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">If we have to make a kind qualified by adjectives, expand that into a suitable subtree</span><span class="named-paragraph-number">8.3</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">val</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Node::get_evaluation</span><span class="plain-syntax">(</span><span class="identifier-syntax">what_to_make</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">val</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">Descriptions::is_adjectives_plus_kind</span><span class="plain-syntax">(</span><span class="identifier-syntax">val</span><span class="plain-syntax">))) {</span>
<span class="plain-syntax">        </span><a href="4-rpt.html#SP7" class="function-link"><span class="function-syntax">Refiner::refine_from_simple_description</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">what_to_make</span><span class="plain-syntax">, </span><span class="identifier-syntax">Node::duplicate</span><span class="plain-syntax">(</span><span class="identifier-syntax">val</span><span class="plain-syntax">));</span>
<span class="plain-syntax">    }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-ass2.html#SP8">&#167;8</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP8_4" class="paragraph-anchor"></a><b>&#167;8.4. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Add this new generalisation to the list for the kind it applies to</span><span class="named-paragraph-number">8.4</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="reserved-syntax">assemblies_data</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ad</span><span class="plain-syntax"> = </span><span class="identifier-syntax">InferenceSubjects::get_assemblies_data</span><span class="plain-syntax">(</span><span class="identifier-syntax">k</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ad</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">generalisation_list</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">ad</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">generalisation_list</span><span class="plain-syntax"> = </span><span class="identifier-syntax">g</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">generalisation</span><span class="plain-syntax"> *</span><span class="identifier-syntax">g2</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ad</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">generalisation_list</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">g2</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">) </span><span class="identifier-syntax">g2</span><span class="plain-syntax"> = </span><span class="identifier-syntax">g2</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">g2</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax"> = </span><span class="identifier-syntax">g</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">g</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-ass2.html#SP8">&#167;8</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP8_5" class="paragraph-anchor"></a><b>&#167;8.5. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue an infinite regress of assemblies problem message</span><span class="named-paragraph-number">8.5</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"Generalisation:\n"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"$T"</span><span class="plain-syntax">, </span><span class="identifier-syntax">look_for</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"$T"</span><span class="plain-syntax">, </span><span class="identifier-syntax">what_to_make</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_AssemblyRegress</span><span class="plain-syntax">),</span>
<span class="plain-syntax">        </span><span class="string-syntax">"this generalisation would be too dangerous"</span><span class="plain-syntax">,</span>
<span class="plain-syntax">        </span><span class="string-syntax">"because it would lead to infinite regress in the assembly process. Sometimes "</span>
<span class="plain-syntax">        </span><span class="string-syntax">"this happens if you have set up matters with text like 'A container is in every "</span>
<span class="plain-syntax">        </span><span class="string-syntax">"container.'."</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-ass2.html#SP8">&#167;8</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP9" class="paragraph-anchor"></a><b>&#167;9. </b>This is used only in checking for infinite regress:
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Assertions::Assemblies::subtree_mentions_kind</span><button class="popup" onclick="togglePopup('usagePopup3')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup3">Usage of <span class="code-font"><span class="function-syntax">Assertions::Assemblies::subtree_mentions_kind</span></span>:<br/><a href="4-ass2.html#SP8">&#167;8</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">subtree</span><span class="plain-syntax">, </span><span class="identifier-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">k</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">level</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">Node::get_type</span><span class="plain-syntax">(</span><span class="identifier-syntax">subtree</span><span class="plain-syntax">) == </span><span class="identifier-syntax">COMMON_NOUN_NT</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax">            (</span><span class="identifier-syntax">Node::get_subject</span><span class="plain-syntax">(</span><span class="identifier-syntax">subtree</span><span class="plain-syntax">) == </span><span class="identifier-syntax">k</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">subtree</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax">) &amp;&amp; (</span><a href="4-ass2.html#SP9" class="function-link"><span class="function-syntax">Assertions::Assemblies::subtree_mentions_kind</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">subtree</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax">, </span><span class="identifier-syntax">k</span><span class="plain-syntax">, </span><span class="identifier-syntax">level</span><span class="plain-syntax">+1)))</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">level</span><span class="plain-syntax">&gt;0) &amp;&amp; (</span><span class="identifier-syntax">subtree</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">) &amp;&amp; (</span><a href="4-ass2.html#SP9" class="function-link"><span class="function-syntax">Assertions::Assemblies::subtree_mentions_kind</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">subtree</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">, </span><span class="identifier-syntax">k</span><span class="plain-syntax">, </span><span class="identifier-syntax">level</span><span class="plain-syntax">)))</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP10" class="paragraph-anchor"></a><b>&#167;10. The assembly process.</b>As noticed above, it's useful to have a routine which brings up to date the
application of generalisations. When this routine completes, every object
of a given kind has undergone every generalisation applicable to it exactly once.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Assertions::Assemblies::ensure_all_generalisations_made</span><button class="popup" onclick="togglePopup('usagePopup4')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup4">Usage of <span class="code-font"><span class="function-syntax">Assertions::Assemblies::ensure_all_generalisations_made</span></span>:<br/><a href="4-ass2.html#SP8">&#167;8</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">k</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">infs</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">LOOP_OVER</span><span class="plain-syntax">(</span><span class="identifier-syntax">infs</span><span class="plain-syntax">, </span><span class="identifier-syntax">inference_subject</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">InferenceSubjects::is_within</span><span class="plain-syntax">(</span><span class="identifier-syntax">infs</span><span class="plain-syntax">, </span><span class="identifier-syntax">k</span><span class="plain-syntax">)) &amp;&amp; (</span><span class="identifier-syntax">KindSubjects::to_kind</span><span class="plain-syntax">(</span><span class="identifier-syntax">infs</span><span class="plain-syntax">) == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">))</span>
<span class="plain-syntax">            </span><a href="4-ass2.html#SP11" class="function-link"><span class="function-syntax">Assertions::Assemblies::satisfies_generalisations</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">infs</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP11" class="paragraph-anchor"></a><b>&#167;11. </b>Clearly one reason we might need to bring generalisations up to date is if
the kind of an object is determined, because that potentially expands the set of
generalisations applicable to it. But it's needlessly slow to apply a full
refresh when we know the only object which can be affected, so in that
situation we call just <span class="extract"><span class="extract-syntax">Assertions::Assemblies::satisfies_generalisations</span></span> on the object in question.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Assertions::Assemblies::satisfies_generalisations</span><button class="popup" onclick="togglePopup('usagePopup5')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup5">Usage of <span class="code-font"><span class="function-syntax">Assertions::Assemblies::satisfies_generalisations</span></span>:<br/><a href="4-ass2.html#SP10">&#167;10</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">infs</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">KindSubjects::to_kind</span><span class="plain-syntax">(</span><span class="identifier-syntax">infs</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">k</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">k</span><span class="plain-syntax"> = </span><span class="identifier-syntax">InferenceSubjects::narrowest_broader_subject</span><span class="plain-syntax">(</span><span class="identifier-syntax">infs</span><span class="plain-syntax">); </span><span class="identifier-syntax">k</span><span class="plain-syntax">; </span><span class="identifier-syntax">k</span><span class="plain-syntax"> = </span><span class="identifier-syntax">InferenceSubjects::narrowest_broader_subject</span><span class="plain-syntax">(</span><span class="identifier-syntax">k</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">application</span><span class="plain-syntax"> *</span><span class="identifier-syntax">app</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">app</span><span class="plain-syntax"> = </span><span class="identifier-syntax">InferenceSubjects::get_assemblies_data</span><span class="plain-syntax">(</span><span class="identifier-syntax">infs</span><span class="plain-syntax">)-&gt;</span><span class="element-syntax">applications_so_far</span><span class="plain-syntax">; </span><span class="identifier-syntax">app</span><span class="plain-syntax">; </span><span class="identifier-syntax">app</span><span class="plain-syntax"> = </span><span class="identifier-syntax">app</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">)</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">app</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">generalisation_owner</span><span class="plain-syntax"> == </span><span class="identifier-syntax">k</span><span class="plain-syntax">)</span>
<span class="plain-syntax">                </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="named-paragraph-container code-font"><a href="4-ass2.html#SP11_1" class="named-paragraph-link"><span class="named-paragraph">Apply generalisations about K which have not yet been applied</span><span class="named-paragraph-number">11.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP11_1" class="paragraph-anchor"></a><b>&#167;11.1. </b>At this point <span class="extract"><span class="extract-syntax">app</span></span> points to the record of which generalisations in \(K\)
have been applied to the object so far, or is <span class="extract"><span class="extract-syntax">NULL</span></span> if none of \(K\)'s
generalisation has ever been applied to it.
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Apply generalisations about K which have not yet been applied</span><span class="named-paragraph-number">11.1</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="reserved-syntax">generalisation</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ignore_up_to</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">app</span><span class="plain-syntax">)?(</span><span class="identifier-syntax">app</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">latest_applied</span><span class="plain-syntax">):</span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">generalisation</span><span class="plain-syntax"> *</span><span class="identifier-syntax">g</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">g</span><span class="plain-syntax"> = </span><span class="identifier-syntax">InferenceSubjects::get_assemblies_data</span><span class="plain-syntax">(</span><span class="identifier-syntax">k</span><span class="plain-syntax">)-&gt;</span><span class="element-syntax">generalisation_list</span><span class="plain-syntax">; </span><span class="identifier-syntax">g</span><span class="plain-syntax">; </span><span class="identifier-syntax">g</span><span class="plain-syntax">=</span><span class="identifier-syntax">g</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ignore_up_to</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">g</span><span class="plain-syntax"> == </span><span class="identifier-syntax">ignore_up_to</span><span class="plain-syntax">) </span><span class="identifier-syntax">ignore_up_to</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">continue</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">app</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="4-ass2.html#SP11_1_1" class="named-paragraph-link"><span class="named-paragraph">Create a new record for this previously unapplied kind</span><span class="named-paragraph-number">11.1.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">app</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">latest_applied</span><span class="plain-syntax"> = </span><span class="identifier-syntax">g</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><a href="4-ass2.html#SP13" class="function-link"><span class="function-syntax">Assertions::Assemblies::satisfies_generalisation</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">infs</span><span class="plain-syntax">, </span><span class="identifier-syntax">g</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-ass2.html#SP11">&#167;11</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP11_1_1" class="paragraph-anchor"></a><b>&#167;11.1.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Create a new record for this previously unapplied kind</span><span class="named-paragraph-number">11.1.1</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="identifier-syntax">app</span><span class="plain-syntax"> = </span><span class="identifier-syntax">CREATE</span><span class="plain-syntax">(</span><span class="reserved-syntax">application</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">app</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">generalisation_owner</span><span class="plain-syntax"> = </span><span class="identifier-syntax">k</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">app</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax"> = </span><span class="identifier-syntax">InferenceSubjects::get_assemblies_data</span><span class="plain-syntax">(</span><span class="identifier-syntax">infs</span><span class="plain-syntax">)-&gt;</span><span class="element-syntax">applications_so_far</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">InferenceSubjects::get_assemblies_data</span><span class="plain-syntax">(</span><span class="identifier-syntax">infs</span><span class="plain-syntax">)-&gt;</span><span class="element-syntax">applications_so_far</span><span class="plain-syntax"> = </span><span class="identifier-syntax">app</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-ass2.html#SP11_1">&#167;11.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP12" class="paragraph-anchor"></a><b>&#167;12. </b>It's worth a brief pause to think about the time and storage needed by the
above. Let \(N\) be the number of objects, and \(H\) the maximum depth of the kinds
hierarchy; while in theory \(H\) might be \(O(N)\), it's more likely to be about
\(\log_2 N\) if the kinds hierarchy is balanced, and in practice even for very
large Inform source texts \(H\) is never larger than 7 or 8.
</p>

<p class="commentary">The storage required to record \(G\) generalisations is proportional to \(G\),
since each appears only in a single linked list and is recorded in a single
structure instance. We clearly won't do better than that.
</p>

<p class="commentary">The storage required to record which generalisations have so far applied to
which objects is \(O(HN)\), since each object stores about \(12H\) bytes of data,
which is significantly better than a bitmap recording all pairs of generalisations
and objects (which would be \(O(GN)\)). The running time of <span class="extract"><span class="extract-syntax">Assertions::Assemblies::satisfies_generalisations</span></span>
applied to object \(X\) is \(O(G_X H^2)\), where \(G_X\) is the number of generalisations
which can be applied to \(X\). In the course of compilation this is called once
each time the kind of \(X\) is changed &mdash; at most \(H\) times &mdash; and once each time
a new generalisation applicable to \(X\) is added &mdash; at most \(G_X\) times. So we
have a total time consumption of \(O(G_X^2 H^2 + G_X H^3)\). In practice the
constants are low, \(G_X\) is very small compared to the size of the source
text, and so is \(H\).
</p>

<p class="commentary">The main point, then, is that the mechanism above is much, much faster than
repeatedly checking each generalisation against each object, for a cost of
\(O(G^2N)\).
</p>

<p class="commentary firstcommentary"><a id="SP13" class="paragraph-anchor"></a><b>&#167;13. </b>So here we get on with the actual construction: we apply <span class="extract"><span class="extract-syntax">g</span></span> to <span class="extract"><span class="extract-syntax">infs</span></span>. What
we actually do is to insert new sentences after the current one.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">implicit_recursion_exception</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">; </span><span class="comment-syntax"> thrown when we've gone into infinite regress</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Assertions::Assemblies::satisfies_generalisation</span><button class="popup" onclick="togglePopup('usagePopup6')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup6">Usage of <span class="code-font"><span class="function-syntax">Assertions::Assemblies::satisfies_generalisation</span></span>:<br/><a href="4-ass2.html#SP11_1">&#167;11.1</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">infs</span><span class="plain-syntax">, </span><span class="reserved-syntax">generalisation</span><span class="plain-syntax"> *</span><span class="identifier-syntax">g</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">counterpart</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">snatcher</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">PluginCalls::detect_bodysnatching</span><span class="plain-syntax">(</span><span class="identifier-syntax">infs</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">snatcher</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">counterpart</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">ASSEMBLIES</span><span class="plain-syntax">, </span><span class="string-syntax">"Body-snatcher found! Subj $j, snatcher %d, counterpart $j\n"</span><span class="plain-syntax">,</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">infs</span><span class="plain-syntax">, </span><span class="identifier-syntax">snatcher</span><span class="plain-syntax">, </span><span class="identifier-syntax">counterpart</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">snatcher</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">infs_k</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Node::get_subject</span><span class="plain-syntax">(</span><span class="identifier-syntax">g</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">substitute_at</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="named-paragraph-container code-font"><a href="4-ass2.html#SP13_1" class="named-paragraph-link"><span class="named-paragraph">Throw the infinite regress exception if the current sentence makes too many things</span><span class="named-paragraph-number">13.1</span></a></span><span class="plain-syntax">;</span>

<span class="plain-syntax">    </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">new_sentence</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Node::new</span><span class="plain-syntax">(</span><span class="identifier-syntax">SENTENCE_NT</span><span class="plain-syntax">);</span>

<span class="plain-syntax">    </span><span class="comment-syntax"> mark this sentence as implicit, and increase its generation count:</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">Node::set_implicit_in_creation_of</span><span class="plain-syntax">(</span><span class="identifier-syntax">new_sentence</span><span class="plain-syntax">, </span><span class="identifier-syntax">infs</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">Annotations::write_int</span><span class="plain-syntax">(</span><span class="identifier-syntax">new_sentence</span><span class="plain-syntax">, </span><span class="identifier-syntax">implicitness_count_ANNOT</span><span class="plain-syntax">,</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">Annotations::read_int</span><span class="plain-syntax">(</span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax">, </span><span class="identifier-syntax">implicitness_count_ANNOT</span><span class="plain-syntax">) + </span><span class="constant-syntax">1</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">Node::set_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">new_sentence</span><span class="plain-syntax">, </span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax">));</span>

<span class="plain-syntax">    </span><span class="comment-syntax"> temporarily make the </span><span class="extract"><span class="extract-syntax">EVERY_NT</span></span><span class="comment-syntax"> node refer to the specific new </span><span class="extract"><span class="extract-syntax">infs</span></span><span class="comment-syntax">:</span>
<span class="plain-syntax">    </span><a href="4-rpt.html#SP1" class="function-link"><span class="function-syntax">Refiner::give_subject_to_noun</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">g</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">substitute_at</span><span class="plain-syntax">, </span><span class="identifier-syntax">infs</span><span class="plain-syntax">);</span>

<span class="plain-syntax">    </span><span class="comment-syntax"> make the new sentence an assertion:</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">new_sentence</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Node::new</span><span class="plain-syntax">(</span><span class="identifier-syntax">VERB_NT</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">new_sentence</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Node::new</span><span class="plain-syntax">(</span><span class="identifier-syntax">CREATED_NT</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">Node::copy_subtree</span><span class="plain-syntax">(</span><span class="identifier-syntax">g</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">look_for</span><span class="plain-syntax">, </span><span class="identifier-syntax">new_sentence</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">new_sentence</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Node::new</span><span class="plain-syntax">(</span><span class="identifier-syntax">CREATED_NT</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">Node::copy_subtree</span><span class="plain-syntax">(</span><span class="identifier-syntax">g</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">what_to_make</span><span class="plain-syntax">, </span><span class="identifier-syntax">new_sentence</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">new_sentence</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>

<span class="plain-syntax">    </span><span class="comment-syntax"> restore the </span><span class="extract"><span class="extract-syntax">EVERY_NT</span></span><span class="comment-syntax"> node, now that the tree containing it has been copied:</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">Node::set_type</span><span class="plain-syntax">(</span><span class="identifier-syntax">g</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">substitute_at</span><span class="plain-syntax">, </span><span class="identifier-syntax">EVERY_NT</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">Node::set_subject</span><span class="plain-syntax">(</span><span class="identifier-syntax">g</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">substitute_at</span><span class="plain-syntax">, </span><span class="identifier-syntax">infs_k</span><span class="plain-syntax">);</span>

<span class="plain-syntax">    </span><span class="comment-syntax"> insert this sentence after the current assembly position:</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">new_sentence</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax"> = </span><span class="identifier-syntax">global_pass_state</span><span class="plain-syntax">.</span><span class="element-syntax">assembly_position</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">global_pass_state</span><span class="plain-syntax">.</span><span class="element-syntax">assembly_position</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax"> = </span><span class="identifier-syntax">new_sentence</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">global_pass_state</span><span class="plain-syntax">.</span><span class="element-syntax">assembly_position</span><span class="plain-syntax"> = </span><span class="identifier-syntax">new_sentence</span><span class="plain-syntax">;</span>

<span class="plain-syntax">    </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">ASSEMBLIES</span><span class="plain-syntax">,</span>
<span class="plain-syntax">        </span><span class="string-syntax">"Subject $j satisfies generalisation %d (from $j), making sentence:\n$T\n"</span><span class="plain-syntax">,</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">infs</span><span class="plain-syntax">, </span><span class="identifier-syntax">g</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">allocation_id</span><span class="plain-syntax">, </span><span class="identifier-syntax">infs_k</span><span class="plain-syntax">, </span><span class="identifier-syntax">new_sentence</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP13_1" class="paragraph-anchor"></a><b>&#167;13.1. </b>The "implicitness count" is a generation count, where the sentences
from the original source text are generation 0, and any sentences created
from those are generation 1, and so on. This should never be more than a
dozen or so, and if it becomes large than we can be pretty sure that the
machinery is in infinite regress, e.g., because each \(K\) must contain an
\(L\) but each \(L\) must contain a \(K\).
</p>

<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">MAX_ASSEMBLY_SIZE</span><span class="plain-syntax"> </span><span class="constant-syntax">500</span>
</pre>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Throw the infinite regress exception if the current sentence makes too many things</span><span class="named-paragraph-number">13.1</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">implicit_recursion_exception</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Annotations::read_int</span><span class="plain-syntax">(</span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax">, </span><span class="identifier-syntax">implicitness_count_ANNOT</span><span class="plain-syntax">) &gt;= </span><span class="constant-syntax">MAX_ASSEMBLY_SIZE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">implicit_recursion_exception</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">Problems::quote_source</span><span class="plain-syntax">(1, </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">Problems::quote_subject</span><span class="plain-syntax">(2, </span><span class="identifier-syntax">infs_k</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">max</span><span class="plain-syntax"> = </span><span class="constant-syntax">MAX_ASSEMBLY_SIZE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">Problems::quote_number</span><span class="plain-syntax">(3, &amp;</span><span class="identifier-syntax">max</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">StandardProblems::handmade_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_AssemblyLoop</span><span class="plain-syntax">));</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">Problems::issue_problem_segment</span><span class="plain-syntax">(</span>
<span class="plain-syntax">            </span><span class="string-syntax">"Making a new %2 seems to result in an assembly which can never end, "</span>
<span class="plain-syntax">            </span><span class="string-syntax">"or which at any rate led to some %3 further constructions "</span>
<span class="plain-syntax">            </span><span class="string-syntax">"before I panicked. This problem tends to occur if instructions "</span>
<span class="plain-syntax">            </span><span class="string-syntax">"are given which cause kinds to create each other forever: "</span>
<span class="plain-syntax">            </span><span class="string-syntax">"for instance, 'Every device is on a supporter. Every supporter "</span>
<span class="plain-syntax">            </span><span class="string-syntax">"is in a container. Every container is part of a device.'"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">Problems::issue_problem_end</span><span class="plain-syntax">();</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-ass2.html#SP13">&#167;13</a>.</li></ul>
<nav role="progress"><div class="progresscontainer">
    <ul class="progressbar"><li class="progressprev"><a href="4-rk.html">&#10094;</a></li><li class="progresschapter"><a href="P-wtmd.html">P</a></li><li class="progresschapter"><a href="1-am.html">1</a></li><li class="progresschapter"><a href="2-bv.html">2</a></li><li class="progresschapter"><a href="3-dlr.html">3</a></li><li class="progresscurrentchapter">4</li><li class="progresssection"><a href="4-nr.html">nr</a></li><li class="progresssection"><a href="4-rpt.html">rpt</a></li><li class="progresssection"><a href="4-tc.html">tc</a></li><li class="progresssection"><a href="4-ass.html">ass</a></li><li class="progresssection"><a href="4-npa.html">npa</a></li><li class="progresssection"><a href="4-pk.html">pk</a></li><li class="progresssection"><a href="4-rk.html">rk</a></li><li class="progresscurrent">ass2</li><li class="progresssection"><a href="4-imp.html">imp</a></li><li class="progresschapter"><a href="5-id.html">5</a></li><li class="progresschapter"><a href="6-rls.html">6</a></li><li class="progresschapter"><a href="7-tc.html">7</a></li><li class="progresschapter"><a href="8-kpr.html">8</a></li><li class="progressnext"><a href="4-imp.html">&#10095;</a></li></ul></div>
</nav><!-- End of weave -->

		</main>
	</body>
</html>

